﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace ConfigManager.Core.Instructions
{
    /// <summary>
    /// 
    /// </summary>
    public class ExternalSectionInstruction : XmlInstruction
    {
        private string _source;
        private string _xpath;

        #region Properties
        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>The source.</value>
        public string Source
        {
            get { return _source; }
            set { _source = value; }
        }

        /// <summary>
        /// Gets or sets the xpath.
        /// </summary>
        /// <value>The xpath.</value>
        public string XPath
        {
            get { return _xpath; }
            set { _xpath = value; }
        }
        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="ExternalSectionInstruction"/> class.
        /// </summary>
        /// <param name="xmlDoc">The XML doc.</param>
        /// <param name="node">The node.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="data">The data.</param>
        public ExternalSectionInstruction(XmlDocument xmlDoc, XmlNode node, IDictionary<string, string> parameters)
            : base ( xmlDoc, node, parameters)
        {
            if (parameters.ContainsKey("source") == false)
                throw new ArgumentException(String.Format(ResourceStrings.MissingParameter, "source"));

            this.Source = parameters["source"];
            if (parameters.ContainsKey("xpath"))
                this.XPath = parameters["xpath"];
        }

        /// <summary>
        /// Runs this instruction.
        /// </summary>
        public override void Run()
        {
            if (PassesConditions())
            {
                if (string.IsNullOrEmpty(_xpath))
                {
                    using (StreamReader sectionFile = new StreamReader(Source))
                        InsertXmlFragment(sectionFile.ReadToEnd(), Node, XmlDoc);
                }
                else
                {
                    XmlDocument externalXmlDoc = new XmlDocument();
                    externalXmlDoc.Load(_source);
                    XmlNodeList list = externalXmlDoc.SelectNodes(XPath);
                    for (int i = list.Count - 1; i >= 0; i--)
                        InsertXmlFragment(list[i].OuterXml, Node, XmlDoc);
                }
            }

            base.Run();
        }
    }
}
